package beans;

import java.sql.*;
import java.util.*;
import bd.*;
import utils.Validador;
import mapping.*;
import utils.GeneradorXML;

public class BeanLugares {

	public int contadorTuplas = -1;
	public int last_id_elem_mapa;

	public BeanLugares() {
		super();
	}

	/** CONSULTAS * */

	public LugarInteres getLugarById(int id_lugar) throws Exception {
		ResultSet rsLugar = null;
		StringBuffer query = new StringBuffer(
				"SELECT * FROM elemento_mapa em, lugar_interes li, tipo_elem_mapa tem "
						+ "WHERE em.id_elem_mapa=li.id_lugar_interes AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa ");
		query.append(" AND em.id_elem_mapa= " + id_lugar + ";");
		try {
			rsLugar = GestorBD.consulta(query);
			if (!rsLugar.next()) {
				throw new SQLException("EL Id " + id_lugar + " NO EXISTE!!");
			}
			LugarInteres li = new LugarInteres();
			li.setId_elem_mapa(rsLugar.getInt("id_elem_mapa"));
			li.setNombre(rsLugar.getString("nombre"));
			li.setDescripcion(rsLugar.getString("descripcion"));
			li.setTipo_elem_mapa(rsLugar.getString("tipo_elem_mapa"));
			li.setLatitud(rsLugar.getDouble("latitud"));
			li.setLongitud(rsLugar.getDouble("longitud"));
			li.setDireccion(rsLugar.getString("direccion"));
			li.setTfnos(getListaTfnos(id_lugar));
			li.setImagenesURL(getListaImagenes(id_lugar));
			System.out.println(li);
			rsLugar.close();
			return li;
		} catch (ConsultaInadecuadaException cie) {
			throw new ConsultaInadecuadaException(cie.toString());
		} catch (SQLException sqle) {
			throw new SQLException(sqle.toString());
		} catch (NullPointerException npe) {
			throw new Exception(npe.toString());
		} catch (Exception e) {
			throw new Exception(e.toString());
		}
	}

	private List getListaTfnos(int id_lugar) throws Exception {
		List tfnosLugarLista = new LinkedList();
		StringBuffer query = new StringBuffer(
				"SELECT * FROM telefono tf, lugar_interes_tfno litf,"
						+ " lugar_interes li WHERE tf.id_telefono = litf.id_tfno AND "
						+ "litf.id_lugar_interes = li.id_lugar_interes "
						+ "AND li.id_lugar_interes = " + id_lugar + ";");
		try {
			ResultSet rsTfnos = GestorBD.consulta(query);
			while (rsTfnos.next()) {
				Telefono t = new Telefono(Integer.parseInt(rsTfnos
						.getString("id_telefono")), rsTfnos
						.getString("telefono"));
				tfnosLugarLista.add(t);
			}
			rsTfnos.close();
		} catch (Exception e) {
			throw new Exception(e.toString());
		}
		return tfnosLugarLista;
	}

	private List getListaImagenes(int id_lugar) throws Exception {
		List imagenesLista = new LinkedList();
		StringBuffer query = new StringBuffer("SELECT * FROM imagen_lugar img"
				+ " WHERE img.id_elem_mapa = " + id_lugar + ";");
		try {
			ResultSet rsImagenes = GestorBD.consulta(query);
			while (rsImagenes.next()) {
				ImagenLugar img = new ImagenLugar(rsImagenes
						.getInt("id_imagen_lugar"), id_lugar, rsImagenes
						.getString("ruta_imagen"), rsImagenes
						.getString("titulo_imagen"));
				imagenesLista.add(img);
			}
			rsImagenes.close();
		} catch (Exception e) {
			throw new Exception(e.toString());
		}
		return imagenesLista;
	}

	/**
	 * @return Lista que contiene todos los tipos (sus literales String) de
	 *         lugares almacenados en la BD
	 */
	public List getTipoLugares() {
		List listTipoLugares = new LinkedList();
		ResultSet rsTipoLugares = null;
		StringBuffer query = new StringBuffer("SELECT * FROM tipo_elem_mapa;");
		try {
			rsTipoLugares = GestorBD.consulta(query);
			while (rsTipoLugares.next()) {
				/*
				 * Tomamos la segunda columna (ColumnIndex = '2'), La primera
				 * columna tiene Id's que nos interesa para relacionar el tipo
				 * de lugar segun FK.Para entender por qu� se ha usado el
				 * formato: [id_tipo_lugar],[nom_tipo_lugar] Ir a
				 * AnadirLugar.jsp y ver metodo split de String Podria haberse
				 * usado arrays de dos elementos(almacenandolos en la lista);
				 * uno para el id y otro para el nombre del tipo de lugar
				 * asociado pero seria mas ineficiente en uso de memoria.
				 */
				listTipoLugares.add(rsTipoLugares.getString(1) + ","
						+ rsTipoLugares.getString(2));
			}
			rsTipoLugares.close();
		} catch (ConsultaInadecuadaException cie) {
			cie.printStackTrace();
		} catch (SQLException sqle) {
			sqle.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listTipoLugares;
	}

	/**
	 * Nos permitir� obtener una informacion completa de cada lugar con sus
	 * latitudes y longitudes e imagenes.Este m�todo ser�a la base para una
	 * posterior escritura del fichero XML y uso en google maps. Este metodo es
	 * valido para mostrar todos aquellos lugares puestos por el/los
	 * administrador/es.
	 * 
	 */
	public List getLugaresLatLngImgYTipo(String id_user) {

		List listElemMapa = new LinkedList();
		StringBuffer query = new StringBuffer("SELECT * FROM ");
		if (!id_user.equals("-1")) {
			query
					.append("elemento_mapa em, lugar_interes li, tipo_elem_mapa tem, usuario u, usuario_elem_mapa uem ");
			query.append("WHERE em.id_elem_mapa=li.id_lugar_interes ");
			query.append("AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa ");
			query.append("AND uem.id_elem_mapa = em.id_elem_mapa ");
			query.append("AND u.id_usuario = uem.id_usuario ");
			query.append("AND u.id_usuario = " + id_user + ";");
		} else {
			query.append("elemento_mapa em, lugar_interes li, tipo_elem_mapa tem ");
			query.append("WHERE em.id_elem_mapa=li.id_lugar_interes ");
			query.append("AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa ");
			query.append("AND em.es_de_interes = 1;");
		}

		try {
			ResultSet rs = GestorBD.consulta(query);
			while (rs.next()) {
				LugarInteres li = new LugarInteres();
				li.setId_elem_mapa(rs.getInt("id_elem_mapa"));
				li.setNombre(rs.getString("nombre"));
				li.setDescripcion(rs.getString("descripcion"));
				li.setLatitud(rs.getDouble("latitud")); // columna de "Latitud"
				li.setLongitud(rs.getDouble("longitud")); // columna de "Longitud"
				li.setTipo_elem_mapa(rs.getString("tipo_elem_mapa"));
				li
						.setEs_de_interes((rs.getString("es_de_interes")
								.equals("1") ? true : false));
				StringBuffer queryImgLugarInteres = new StringBuffer(
						"SELECT * FROM elemento_mapa em , imagen_lugar il ");
				queryImgLugarInteres
						.append(" WHERE em.id_elem_mapa=il.id_elem_mapa AND em.id_elem_mapa = ");
				queryImgLugarInteres.append(rs.getInt("id_elem_mapa") + ";");
				ResultSet rs2 = GestorBD.consulta(queryImgLugarInteres);
				while (rs2.next()) {
					ImagenLugar img = new ImagenLugar(rs2
							.getInt("id_imagen_lugar"), rs2
							.getInt("id_elem_mapa"), rs2
							.getString("ruta_imagen"), rs2
							.getString("titulo_imagen"));
					li.getImagenesURL().add(img);
				}
				listElemMapa.add(li);
				rs2.close();
			}
			rs.close();
		} catch (ConsultaInadecuadaException cie) {
			System.err.println("### CONSULTA Inadecuada en getLugaresLatLng()");
		} catch (SQLException sqe) {
			System.err
					.println("ERROR en la consulta de BD ; metodo getLugaresLatLng()");
		} catch (Exception e) {
			System.err.println("### Error Desconocido en getLugaresLatLng!");
		}
		return listElemMapa;
	}

	/**
	 * Metodo que dado el id del usuario que se toma como parametro devuelve los
	 * lugares que tiene almacenados en su cuenta. Ej: Para el usuario "Pepe"
	 * sus lugares seran por ejemplo: "La alameda", "B3" o cualquier otro que
	 * haya creado
	 * 
	 * @param idUser
	 * @return
	 * @throws Exception
	 */
	public List getLugaresUsuario(String idUser) throws Exception {
		StringBuffer queryIdUser = new StringBuffer(
				"SELECT * FROM usuario_elem_mapa WHERE id_usuario = " + idUser
						+ ";");
		List listado = new LinkedList();
		try {
			ResultSet rsuem = GestorBD.consulta(queryIdUser);
			while (rsuem.next()) {
				String id_elem_mapa = rsuem.getString("id_elem_mapa");
				LugarInteres li = getLugarById(Integer.parseInt(id_elem_mapa));
				listado.add(li);
			}
			rsuem.close();

		} catch (ConsultaInadecuadaException e) {
			e.printStackTrace();
			throw new ConsultaInadecuadaException(e.toString());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
		return listado;
	}

	/**
	 * 
	 * @param tipoLugar
	 * @param nombreLugar
	 * @param cantidadTuplas:
	 *            el numero de tuplas que se desean obtener de la busqueda
	 * @param cursor:
	 *            Tupla a partir del cual vamos a tomar los datos del resultset
	 *            en su totalidad
	 * @param id_usuario:
	 *            Si es -1 se entendera que no se quiere buscar en los lugares
	 *            favoritos del usuario
	 * @param busq_interes:
	 *            si vale 1, solo busca lugares de interes si vale 2, solo busca
	 *            lugares que no son de interes e.o.c. busca tanto lugares de
	 *            interes como no de interes
	 * @return
	 * @throws Exception
	 */
	public List getLugares(String[] tipoLugar, String nombreLugar,
			int cantidadTuplas, int cursor, String id_usuario, int busq_interes)
			throws Exception {

		System.out.println("Num tuplas por pagina: " + cantidadTuplas
				+ "Cursor en : " + cursor);
		List listElemMapa = new LinkedList();
		ResultSet rsLugares = null;
		ResultSet rsContLugares = null;
		/*
		 * para  consulta de contar numero de filas 
		 */
		StringBuffer queryCount = new StringBuffer("SELECT COUNT(*) "); 
		/*
		 * para consulta con info de cada tupla
		 */
		StringBuffer query = new StringBuffer("SELECT * "); 
		/*
		 * las dos anteriores haranuso de la subquery
		 */
		StringBuffer subquery = new StringBuffer();

		// sila consulta no proviene de un usuario concreto ...
		if (id_usuario.equals("-1")) {
			// se hace una busqueda por los lugares de interes (es_de_interes =1)
			subquery
					.append("FROM elemento_mapa em, lugar_interes li, tipo_elem_mapa tem ");
			subquery.append("WHERE em.id_elem_mapa=li.id_lugar_interes "
					+ "AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa "
					+ "AND em.es_de_interes=1");
		}
		// si la busqueda es por un usuario...
		else {
			subquery
					.append("FROM usuario_elem_mapa uem, elemento_mapa em,lugar_interes li, tipo_elem_mapa tem "
							+ "WHERE uem.id_elem_mapa = em.id_elem_mapa AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa "
							+ "AND em.id_elem_mapa=li.id_lugar_interes AND uem.id_usuario="
							+ id_usuario);
			if (busq_interes == 1) { // solo lugares NO DE INTERES
				subquery.append(" AND em.es_de_interes=1");
			} else if (busq_interes == 2) { // solo lugares DE INTERES
				subquery.append(" AND em.es_de_interes=0");
			}
		}
		// Aqui se completa/concretiza m�s, los demas parametros de busqueda:
		// nombre , seleccion de tipo y ordenacion
		if (nombreLugar != null || tipoLugar != null) {
			if (nombreLugar != null && nombreLugar.length() != 0) {
				subquery.append(" AND em.nombre LIKE '%" + nombreLugar + "%'");
			}
			if (tipoLugar != null && tipoLugar.length > 0) {
				subquery.append(" AND (");
				for (int i = 0; i < tipoLugar.length - 1; i++) {
					subquery.append(" em.id_tipo_elem_mapa = " + tipoLugar[i]
							+ " OR ");
				}
				subquery.append(" em.id_tipo_elem_mapa = "
						+ tipoLugar[tipoLugar.length - 1] + ")");
			}
		}

		subquery.append(" ORDER BY em.nombre;");

		query.append(subquery);
		queryCount.append(subquery);

		System.out.println(query.toString());

		try {
			rsLugares = GestorBD.consulta(query);
			rsContLugares = GestorBD.consulta(queryCount);
			if (rsContLugares.next()) {
				contadorTuplas = rsContLugares.getInt(1);
			}
			// No se puede posicionar directamente en Cero->E.O.C : EXCEPCION
			if (cursor > 0)
				rsLugares.absolute(cursor);

			int i = 0;
			System.out.println("Obteniendo " + cantidadTuplas
					+ " filas a partir de :" + cursor);
			while (rsLugares.next() && i < cantidadTuplas) {
				LugarInteres li = new LugarInteres(rsLugares
						.getInt("id_elem_mapa"), rsLugares.getString("nombre"),
						rsLugares.getString("descripcion"), rsLugares
								.getString("tipo_elem_mapa"), (rsLugares
								.getString("es_de_interes").equals("1") ? true
								: false), rsLugares.getDouble("latitud"),
						rsLugares.getDouble("longitud"), rsLugares
								.getString("direccion"));
				System.out.println("$$_ " + li.getNombre());
				li.setTfnos(getListaTfnos(rsLugares.getInt("id_elem_mapa")));
				li.setImagenesURL(getListaImagenes(rsLugares
						.getInt("id_elem_mapa")));
				listElemMapa.add(li);
				i++;
			}
			rsLugares.close();
		} catch (ConsultaInadecuadaException cie) {
			throw new ConsultaInadecuadaException("getLugaresLatLng()"
					+ cie.toString());
		} catch (SQLException sqe) {
			throw new SQLException("getLugaresLatLng()" + sqe.toString());
		} catch (Exception e) {
			throw new Exception("getLugaresLatLng()" + e.toString());
		}

		return listElemMapa;
	}

	public List getLugares(String[] tipoLugar, String nombreLugar,
			String id_usuario, int busq_interes) throws Exception {

		List listElemMapa = new LinkedList();
		ResultSet rsLugares = null;
		StringBuffer query = new StringBuffer("SELECT * "); 
		StringBuffer subquery = new StringBuffer();

		// sila consulta no proviene de un usuario concreto ...
		if (id_usuario.equals("-1")) {
			// se hace una busqueda por los lugares de interes (es_de_interes = 1)
			subquery
					.append("FROM elemento_mapa em, lugar_interes li, tipo_elem_mapa tem ");
			subquery.append("WHERE em.id_elem_mapa=li.id_lugar_interes "
					+ "AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa "
					+ "AND em.es_de_interes=1");
		}
		// si la busqueda es por un usuario...
		else {
			subquery
					.append("FROM usuario_elem_mapa uem, elemento_mapa em,lugar_interes li, tipo_elem_mapa tem "
							+ "WHERE uem.id_elem_mapa = em.id_elem_mapa AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa "
							+ "AND em.id_elem_mapa=li.id_lugar_interes AND uem.id_usuario="
							+ id_usuario);
			if (busq_interes == 1) { // solo lugares NO DE INTERES
				subquery.append(" AND em.es_de_interes=1");
			} else if (busq_interes == 2) { // solo lugares DE INTERES
				subquery.append(" AND em.es_de_interes=0");
			}
		}
		// Aqui se completa/concretiza mas, los demas parametros de busqueda:
		// nombre , seleccion de tipo y ordenacion
		if (nombreLugar != null || tipoLugar != null) {
			if (nombreLugar != null && nombreLugar.length() != 0) {
				subquery.append(" AND em.nombre LIKE '%" + nombreLugar + "%'");
			}
			if (tipoLugar != null && tipoLugar.length > 0) {
				subquery.append(" AND (");
				for (int i = 0; i < tipoLugar.length - 1; i++) {
					subquery.append(" em.id_tipo_elem_mapa = " + tipoLugar[i]
							+ " OR ");
				}
				subquery.append(" em.id_tipo_elem_mapa = "
						+ tipoLugar[tipoLugar.length - 1] + ")");
			}
		}

		subquery.append(" ORDER BY em.nombre;");

		query.append(subquery);

		System.out.println(query.toString());

		try {
			rsLugares = GestorBD.consulta(query);
			while (rsLugares.next()) {
				LugarInteres li = new LugarInteres(rsLugares
						.getInt("id_elem_mapa"), rsLugares.getString("nombre"),
						rsLugares.getString("descripcion"), rsLugares
								.getString("tipo_elem_mapa"), (rsLugares
								.getString("es_de_interes").equals("1") ? true
								: false), rsLugares.getDouble("latitud"),
						rsLugares.getDouble("longitud"), rsLugares
								.getString("direccion"));
				System.out.println("$$_ " + li.getNombre());
				li.setTfnos(getListaTfnos(rsLugares.getInt("id_elem_mapa")));
				li.setImagenesURL(getListaImagenes(rsLugares
						.getInt("id_elem_mapa")));
				listElemMapa.add(li);
			}
			rsLugares.close();
		} catch (ConsultaInadecuadaException cie) {
			throw new ConsultaInadecuadaException("getLugaresLatLng()"
					+ cie.toString());
		} catch (SQLException sqe) {
			throw new SQLException("getLugaresLatLng()" + sqe.toString());
		} catch (Exception e) {
			throw new Exception("getLugaresLatLng()" + e.toString());
		}

		return listElemMapa;
	}

	public boolean insertaLugarUsuario(String id_usuario, String[] id_lugares)
			throws SQLException, Exception {
		StringBuffer query = new StringBuffer(
				"INSERT INTO usuario_elem_mapa (id_usuario, id_elem_mapa) VALUES (?, ?);");
		String[] params = new String[2];
		String id_lugar = "";
		params[0] = id_usuario;
		if (id_usuario == null || id_usuario.length() == 0)
			throw new NullPointerException(
					"Ha ocurrido un error durante la inserci�n del lugar favorito: el usuario es nulo o vacio");
		if (id_lugares == null || id_lugares.length == 0)
			throw new NullPointerException(
					"Ha ocurrido un error durante la inserci�n del lugar favorito: la lista de lugares es vacia");
		try {
			GestorBD.comenzarTransaccion();
			for (int i = 0; i < id_lugares.length; i++) {
				id_lugar = id_lugares[i];
				params[1] = id_lugar;
				GestorBD.inserta(query, params);
				System.out.println("Insertado: " + id_usuario + "--->"
						+ id_lugar);
			}
			GestorBD.hacerCommit();
		} catch (SQLException e) {
			throw new SQLException(
					"El lugar "
							+ getNombreLugar(id_lugar)
							+ " no ha podido ser a&ntilde;adido como favorito porque ya fue agregado anteriormente");
		} catch (Exception e) {
			throw new Exception(
					"El lugar no ha podido ser agregado como favorito");
		}
		return true;
	}

	private String getNombreLugar(String idLugar) {
		String nombreLugar = "";
		try {
			LugarInteres lugar = getLugarById(Integer.parseInt(idLugar));
			nombreLugar = lugar.getNombre();
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return nombreLugar;
	}

	public boolean insertaLugarFavoritoUsuario(String id_usuario)
			throws Exception {
		StringBuffer query = new StringBuffer(
				"INSERT INTO usuario_elem_mapa (id_usuario, id_elem_mapa) VALUES (?, ?);");
		String[] params = { id_usuario };
		try {
			System.out.println("Se va a insertar: " + id_usuario + "--->");
			GestorBD.inserta(query, params);
			System.out.println("Insertado: " + id_usuario + "--->");
		} catch (NullPointerException e) {
			e.printStackTrace();
			throw new NullPointerException(e.toString());
		} catch (IndexOutOfBoundsException e) {
			e.printStackTrace();
			throw new IndexOutOfBoundsException(e.toString());
		} catch (SQLException e) {
			e.printStackTrace();
			throw new SQLException(e.toString());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
		return true;
	}

	/**
	 * Este metodo se ocupa de insertar un nuevo lugar en la BD desde la vista
	 * de Usuario registrado
	 * 
	 * @throws Exception
	 */
	public boolean insertaLugar(List paramElemMapa, List paramLugarInteres,
			List tfnos, String id_usuario) throws Exception {
		System.out.println("Insertando lugar .....");
		StringBuffer queryInsertEM = new StringBuffer(
				"INSERT INTO elemento_mapa(nombre, descripcion, id_tipo_elem_mapa, es_de_interes) VALUES(?,?,?,?)");
		StringBuffer queryInsertLI = new StringBuffer(
				"INSERT INTO lugar_interes(id_lugar_interes,latitud, longitud, direccion) VALUES(?,?,?,?);");
		StringBuffer queryInsertUser = new StringBuffer(
				"INSERT INTO usuario_elem_mapa (id_usuario, id_elem_mapa) VALUES (?, ?);");

		if (paramElemMapa == null || paramElemMapa.isEmpty()) {
			throw new NullPointerException("La lista de parametros es vacia");
		}
		if (paramLugarInteres == null || paramLugarInteres.isEmpty()) {
			throw new NullPointerException("La lista de parametros es vacia");
		}
		if (id_usuario == null)
			throw new NullPointerException("El usuario no es correcto");
		precondicionLugar(paramElemMapa, paramLugarInteres, tfnos);
		try {
			GestorBD.comenzarTransaccion();
			/* Parametros de ElemMapa */
			int id_elem_mapa = GestorBD.inserta(queryInsertEM, paramElemMapa);
			last_id_elem_mapa = id_elem_mapa;
			System.out.println("==== ElemMapa insertado: " + id_elem_mapa);
			// a�adimos el id_elem_mapa a la lista de parametros de lugar
			// interes
			paramLugarInteres.add(0, String.valueOf(id_elem_mapa));
			/* Parametros de LugarInteres */
			int id_lugar_interes = GestorBD.inserta(queryInsertLI,
					paramLugarInteres);
			System.out.println("==== LugarInteres insertado: "
					+ id_lugar_interes);
			insertaTelefonos(id_lugar_interes, tfnos);
			// insertaImagenes(id_lugar_interes, imagenes);
			if (!id_usuario.equals("-1")) {
				String[] params = new String[2];
				params[0] = id_usuario;
				params[1] = String.valueOf(id_elem_mapa);
				GestorBD.inserta(queryInsertUser, params);
				System.out.println("Insertado para el usuario: " + id_usuario
						+ " el lugar: " + id_elem_mapa);
			}
			GestorBD.hacerCommit();
			System.out.println("Lugar insertado correctamente");
		} catch (ConsultaInadecuadaException e) {
			e.printStackTrace();
			throw new ConsultaInadecuadaException(e.toString());
		} catch (SQLException e) {
			e.printStackTrace();
			throw new SQLException(e.toString());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
		return true;
	}

	private void insertaTelefonos(int id_lugar_interes, List tfnos)
			throws Exception {
		StringBuffer queryInsertTfno = new StringBuffer(
				"INSERT INTO Telefono(telefono) VALUES (?);");
		StringBuffer queryInsertLIT = new StringBuffer(
				"INSERT INTO lugar_interes_tfno(id_lugar_interes, id_tfno) VALUES (?,?);");
		// si hay numeros de tfno que procesar...
		if (!tfnos.isEmpty()) {
			Iterator it = tfnos.iterator();
			while (it.hasNext()) {

				Object tfno = it.next();
				System.out.println(tfno.getClass());
				String tipoObjeto = tfno.getClass().getName();
				String numero = null;
				boolean esTelefono;

				if (tipoObjeto.indexOf("Telefono") >= 0) {
					Telefono t1 = (Telefono) tfno;
					numero = t1.getTelefono();

				} else if (tipoObjeto.indexOf("String") >= 0) {
					String s1 = tfno.toString();
					numero = s1;
				}
				System.out.println("A validar este numero :  " + numero);
				esTelefono = Validador.esNumeroTelefono(numero);
				if (esTelefono) {
					int id_tfno = GestorBD.inserta(queryInsertTfno, numero);
					System.out.println("===== Tfno insertado: " + id_tfno
							+ "-->" + tfno);
					String[] parLugarTfno = { String.valueOf(id_lugar_interes),
							String.valueOf(id_tfno) };
					try {
						GestorBD.inserta(queryInsertLIT, parLugarTfno);
					} catch (NullPointerException e) {
						e.printStackTrace();
						throw new NullPointerException(e.toString());
					} catch (IndexOutOfBoundsException e) {
						e.printStackTrace();
						throw new IndexOutOfBoundsException(e.toString());
					} catch (SQLException e) {
						e.printStackTrace();
						throw new SQLException(e.toString());
					} catch (Exception e) {
						e.printStackTrace();
						throw new Exception(e.toString());
					}
				}
			}
		}
	}

	/**
	 * 
	 * @param tipoLugar
	 * @param nombreLugar
	 * @return
	 * @throws Exception
	 */
	public List getLugares(String[] tipoLugar, String nombreLugar)
			throws Exception {
		List listElemMapa = new LinkedList();
		ResultSet rsLugares = null;
		StringBuffer query = new StringBuffer();
		query
				.append("SELECT * FROM `elemento_mapa` em, `lugar_interes` li, tipo_elem_mapa tem "
						+ "WHERE em.id_elem_mapa=li.id_lugar_interes AND tem.id_tipo_elem_mapa = em.id_tipo_elem_mapa ");

		if (nombreLugar != null || tipoLugar != null) {
			if (nombreLugar != null && nombreLugar.length() != 0) {
				query.append(" AND em.`nombre` LIKE '%" + nombreLugar + "%'");
			}
			if (tipoLugar != null && tipoLugar.length > 0) {
				query.append(" AND (");
				for (int i = 0; i < tipoLugar.length - 1; i++) {
					query.append(" em.id_tipo_elem_mapa = " + tipoLugar[i]
							+ " OR ");
				}
				query.append(" em.id_tipo_elem_mapa = "
						+ tipoLugar[tipoLugar.length - 1] + ")");
			}
		}
		query.append(" ORDER BY em.nombre;");
		try {
			rsLugares = GestorBD.consulta(query);
			while (rsLugares.next()) {
				LugarInteres li = new LugarInteres();
				li.setId_elem_mapa(rsLugares.getInt(1));
				li.setNombre(rsLugares.getString(2));
				li.setDescripcion(rsLugares.getString(3));
				li.setTipo_elem_mapa(rsLugares.getString(11));
				li.setLatitud(rsLugares.getDouble(7));
				li.setLongitud(rsLugares.getDouble(8));
				li.setDireccion(rsLugares.getString(9));
				li.setEs_de_interes((rsLugares.getString(5).equals("1") ? true
						: false));
				li.setTfnos(getListaTfnos(rsLugares.getInt("id_elem_mapa")));
				li.setImagenesURL(getListaImagenes(rsLugares
						.getInt("id_elem_mapa")));
				listElemMapa.add(li);
			}
			rsLugares.close();
		} catch (ConsultaInadecuadaException cie) {
			throw new ConsultaInadecuadaException("getLugaresLatLng()"
					+ cie.toString());
		} catch (SQLException sqe) {
			throw new SQLException("getLugaresLatLng()" + sqe.toString());
		} catch (Exception e) {
			throw new Exception("getLugaresLatLng()" + e.toString());
		}

		return listElemMapa;
	}

	/** ACTUALIZACIONES * */

	public boolean actualizaLugar(List paramsElemMapa, List paramsLugar,
			List listaTfnos, String listaTfnosElim, String id_lugar) {
		StringBuffer query1 = new StringBuffer(
				"UPDATE elemento_mapa em SET em.nombre = ?, em.descripcion = ?, em.id_tipo_elem_mapa = ?");
		query1.append(" WHERE em.id_elem_mapa = " + id_lugar);

		// Se ha cambiado el orden de los atributos en la sentencia precompilada
		StringBuffer query2 = new StringBuffer(
				"UPDATE lugar_interes li SET li.latitud = ?, li.longitud = ?, li.direccion = ?");
		query2.append(" WHERE li.id_lugar_interes = " + id_lugar);
		precondicionLugar(paramsElemMapa, paramsLugar, listaTfnos);
		try {
			GestorBD.comenzarTransaccion();
			// primero actualizamos los parametros relativos a la tabla
			// Elemento_mapa
			GestorBD.actualiza(query1, paramsElemMapa);
			// actualizamos los parametros relativos a Lugar_interes
			GestorBD.actualiza(query2, paramsLugar);
			// actualizamos la lista de telefonos
			actualizaTfnos(listaTfnos, id_lugar);
			// borramos la lista de telefonos
			borraListaTfnos(listaTfnosElim);
			GestorBD.hacerCommit();
		} catch (Exception e) {
			System.out.println("Error al actualizar: " + e.toString());
			return false;
		}
		return true;
	}

	private void actualizaTfnos(List listaTfnos, String id_lugar)
			throws Exception {
		if (listaTfnos != null) {
			Iterator it = listaTfnos.iterator();
			while (it.hasNext()) {
				Telefono tfno = (Telefono) it.next();
				if (!Validador.esNumeroTelefono(tfno.getTelefono())) {
					throw new Exception("El numero de telefono es incorrecto");
				}
				// si el id del tfno != 0 --> actualiza
				if (tfno.getId_telefono() != 0)
					actualizaTfno(tfno);
				// sino, inserta un nuevo telefono
				else
					insertaTfno(tfno, id_lugar);
			}
		}
	}

	private void actualizaTfno(Telefono tfno) throws Exception {
		StringBuffer queryUpd = new StringBuffer(
				"UPDATE telefono SET telefono = ? WHERE id_telefono = ?");
		String values[] = { tfno.getTelefono(),
				String.valueOf(tfno.getId_telefono()) };
		try {
			GestorBD.actualiza(queryUpd, values);
		} catch (NullPointerException e) {

			e.printStackTrace();
			throw new NullPointerException(e.toString());
		} catch (SQLException e) {

			e.printStackTrace();
			throw new SQLException(e.toString());
		} catch (ConsultaInadecuadaException e) {

			e.printStackTrace();
			throw new ConsultaInadecuadaException(e.toString());
		} catch (Exception e) {

			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}

	private void insertaTfno(Telefono tfno, String id_lugar) throws Exception {
		StringBuffer queryIns1 = new StringBuffer(
				"INSERT INTO telefono(telefono) VALUES (?);");
		StringBuffer queryIns2 = new StringBuffer(
				"INSERT INTO lugar_interes_tfno(id_lugar_interes, id_tfno) VALUES (?, ?);");
		try {
			/*
			 * NO HACE FALTA TRANSACCION PQ YA ESTA DENTRO DE UNA EN
			 * actualizaLugar primero inserta el tfno en la tabla Telefono y
			 * obtiene su id
			 */
			int id_tfno = GestorBD.inserta(queryIns1, tfno.getTelefono());
			/*
			 * despues inserta en la tabla Lugar_Interes_Tfno con el id_lugar y
			 * el id_tfno anterior
			 */
			String values[] = { id_lugar, String.valueOf(id_tfno) };
			GestorBD.inserta(queryIns2, values);
		} catch (NullPointerException e) {

			e.printStackTrace();
			throw new NullPointerException(e.toString());
		} catch (IndexOutOfBoundsException e) {

			e.printStackTrace();
			throw new IndexOutOfBoundsException(e.toString());
		} catch (SQLException e) {

			e.printStackTrace();
			throw new SQLException(e.toString());
		} catch (ConsultaInadecuadaException e) {

			e.printStackTrace();
			throw new ConsultaInadecuadaException(e.toString());
		} catch (Exception e) {

			e.printStackTrace();
			throw new Exception(e.toString());
		}
	}

	private void borraListaTfnos(String listaTfnos) throws Exception {
		StringBuffer query = new StringBuffer(
				"DELETE FROM telefono WHERE id_telefono = ?;");
		if (listaTfnos.length() > 0) {
			String idsTfnos[] = listaTfnos.split(",");
			try {
				GestorBD.borra(query, idsTfnos);
				System.out.println("Borradas ");
			} catch (NullPointerException e) {
				e.printStackTrace();
				throw new NullPointerException(e.toString());
			} catch (SQLException e) {
				e.printStackTrace();
				throw new SQLException(e.toString());
			} catch (ConsultaInadecuadaException e) {
				e.printStackTrace();
				throw new ConsultaInadecuadaException(e.toString());
			} catch (Exception e) {
				e.printStackTrace();
				throw new Exception(e.toString());
			}
		} else
			System.out.println("No hay telefonos que borrar");
	}

	/** BORRADO * */

	/**
	 * 
	 * @param chkboxes
	 * @return Booleano que indica si el borrado ha sido satisfactorio
	 * @throws Exception
	 */
	public boolean borraLugares(String[] chkboxes) throws Exception {
		StringBuffer queryDelete = new StringBuffer(
				"DELETE FROM elemento_mapa WHERE id_elem_mapa=?;");
		StringBuffer queryUpd = new StringBuffer("UPDATE elemento_mapa em SET es_de_interes = 0 ");
		queryUpd.append("WHERE id_elem_mapa = ?;");
		for(int i=0;i<chkboxes.length;i++) {
			try {
			// si el lugar lo tiene algun usuario como favorito
			if(esFavorito(chkboxes[i])) {
				// se actualiza y se le pone es_de_interes a 0
				GestorBD.actualiza(queryUpd, chkboxes[i]);
			}
			else
				// se elimina
				GestorBD.borra(queryDelete, chkboxes);
			} catch (NullPointerException e) {
				e.printStackTrace();
				throw new NullPointerException(e.toString());
			} catch (ConsultaInadecuadaException e) {
				e.printStackTrace();
				throw new ConsultaInadecuadaException(e.toString());
			} catch (SQLException e) {
				e.printStackTrace();
				throw new SQLException(e.toString());
			} catch (Exception e) {
				e.printStackTrace();
				throw new Exception(e.toString());
			}
		}	
		return true;
	}

	private boolean esFavorito(String idLugar) {
		boolean esFav = false;
		StringBuffer query = new StringBuffer("SELECT * FROM usuario_elem_mapa WHERE id_elem_mapa = " + idLugar + ";");
		ResultSet rs;
		try {
			rs = GestorBD.consulta(query);
			// si la consula devuelve resultados
			if(rs.next())
				esFav = true;
		} catch (ConsultaInadecuadaException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return esFav;
	}
	public boolean borraLugaresFavoritos(String id_usuario, String[] chkboxes)
			throws Exception {
		StringBuffer queryDelete = new StringBuffer(
				"DELETE FROM usuario_elem_mapa WHERE id_usuario=" + id_usuario);
		queryDelete = queryDelete.append(" AND id_elem_mapa=?");

		StringBuffer queryDelete2 = new StringBuffer(
				"DELETE FROM elemento_mapa WHERE id_elem_mapa=? AND es_de_interes=0;");

		try {
			GestorBD.comenzarTransaccion();
			GestorBD.borra(queryDelete, chkboxes);
			GestorBD.borra(queryDelete2, chkboxes);
			GestorBD.hacerCommit();
		} catch (NullPointerException e) {
			e.printStackTrace();
			throw new NullPointerException(e.toString());
		} catch (ConsultaInadecuadaException e) {
			e.printStackTrace();
			throw new ConsultaInadecuadaException(e.toString());
		} catch (SQLException e) {
			e.printStackTrace();
			throw new SQLException(e.toString());
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.toString());
		}
		return true;
	}

	/**
	 * Funcion que verifica si se cumplen las restricciones de insercion y
	 * actualizacion de un lugar
	 * 
	 * @param paramsElemMapa
	 * @param paramsLugar
	 * @param listaTfnos
	 */
	private void precondicionLugar(List paramsElemMapa, List paramsLugar,
			List listaTfnos) {
		String nombre = (String) paramsElemMapa.get(0);
		String latitud = (String) paramsLugar.get(0);
		String longitud = (String) paramsLugar.get(1);
		System.out.println(latitud + "----" + longitud);
		// comprueba q el nombre del lugar no sea vacio
		if (nombre == null || nombre.length() == 0) {
			throw new NullPointerException(
					"El nombre del lugar no puede ser vacio");
		}
		// comprueba q la latitud y la longitud no sean vacias
		if (latitud == null || latitud.length() == 0 || longitud == null
				|| longitud.length() == 0) {
			throw new NullPointerException(
					"La latitud o la longitud son vacias");
		}
	}

	public List getLugaresRuta(String id_ruta) throws Exception {

		StringBuffer query = new StringBuffer(
				"SELECT * FROM ruta_lugar rl, ruta_interes ri, elemento_mapa em, lugar_interes li, tipo_elem_mapa tem "
						+ "WHERE rl.id_ruta = ri.id_ruta_interes"
						+ " AND tem.id_tipo_elem_mapa= em.id_tipo_elem_mapa "
						+ " AND rl.id_lugar=li.id_lugar_interes"
						+ " AND li.id_lugar_interes = em.id_elem_mapa");
		query.append(" AND ri.id_ruta_interes = " + id_ruta + ";");
		List lugaresRuta = new LinkedList();
		try {
			ResultSet rsRuta = GestorBD.consulta(query);
			while (rsRuta.next()) {
				LugarInteres li = new LugarInteres(rsRuta
						.getInt("id_elem_mapa"), rsRuta.getString("nombre"),
						rsRuta.getString("descripcion"), rsRuta
								.getString("tipo_elem_mapa"), (rsRuta
								.getString("es_de_interes").equals("1") ? true
								: false), rsRuta.getDouble("latitud"), rsRuta
								.getDouble("longitud"), rsRuta
								.getString("direccion"));
				lugaresRuta.add(li);
			}

		} catch (SQLException sqe) {
			throw new SQLException("Hubo problemas con la consulta o con la BD");
		} catch (ConsultaInadecuadaException cie) {
			throw new ConsultaInadecuadaException("Sentencia no permitida");
		} catch (Exception e) {
			throw new Exception("Error desconocido");
		}
		return lugaresRuta;
	}

	public List getRutas() throws Exception {
		StringBuffer query = new StringBuffer("SELECT * FROM ruta_interes;");
		List listaRutas = new LinkedList();
		try {
			ResultSet rsRutas = GestorBD.consulta(query);
			while (rsRutas.next()) {
				RutaInteres ri = new RutaInteres();
				ri.setId_ruta_interes(Integer.parseInt(rsRutas
						.getString("id_ruta_interes")));
				listaRutas.add(ri);
			}
		} catch (SQLException sqe) {
			throw new SQLException("Hubo problemas con la consulta o con la BD");
		} catch (ConsultaInadecuadaException cie) {
			throw new ConsultaInadecuadaException("Sentencia no permitida");
		} catch (Exception e) {
			throw new Exception("Error desconocido");
		}
		return listaRutas;
	}

	public static void main(String args[]) {
	}

	public void generaXMLLugares(String gmail, String id_usuario) {
		GeneradorXML.generaFicheroXML(true, gmail, id_usuario, null);
	}

	public void generaXMLLugares(String nuevoFichero, List lugares) {
		GeneradorXML.generaFicheroXML(nuevoFichero, lugares);
	}

	public void generaXMLLugares(String nuevoFichero, List lugares,
			String id_usuario) {
		GeneradorXML.generaFicheroXML(nuevoFichero, lugares);
	}

	public void generaXMLLugaresBusqueda(String nuevoFichero,
			String id_usuario, List lugaresBusqueda) {
		GeneradorXML.generaFicheroXML(true, nuevoFichero, id_usuario,
				lugaresBusqueda);
	}

	public void generaFicheroXMLTipoLugares() {
		GeneradorXML.generaFicheroXMLTipoLugares(true);
	}

	public void generaFicheroXMLRutas() {
		GeneradorXML.generaFicheroXMLRutasInteres(true, null, null);
	}

	public void borraFicheroBusquedas(String nombre) {

		System.out.println(GeneradorXML.destruyeFichero(nombre));
	}

	public void conectar() {
		try {
			GestorBD.conectar();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void desconectar() {
		try {
			GestorBD.desconectar();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
